{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}}
{\colortbl ;\red0\green0\blue0;}
\viewkind4\uc1\pard\nowidctlpar\cf1\f0\fs20 The CNS format\par
==============\par
M.U.G.E.N, (c) Elecbyte 2002\par
Documentation for version 2002.04.14\par
\par
\cf0 Beta-release documentation (incomplete)\par
\cf1 Updated 8 January 2002\par
\par
\par
\par
====================================================================\par
0. Contents\par
====================================================================\par
Section I.    Introduction\par
Section II.   Player Variables\par
Section III.  States\par
Section IV.   Expressions\par
Appendix A.   Special State Numbers\par
\par
\par
\par
====================================================================\par
I. Introduction\par
====================================================================\par
\par
The CNS file of a player serves two purposes:\par
i. It defines the variables of that player, such as walking speed, drawing scale factor, and so on.\par
ii. It contains the states of the player, which describe all the moves that the player can do. States are the building blocks that you can use to create simple as well as complicated moves.\par
\par
Like many other character files, the CNS is a text file that you can edit with any text editor. \par
\par
In the CNS file, a semicolon (;) is considered a "comment" character. Any text on the same line after the semicolon will be ignored by the program. The CNS is mostly case-insensitive, i.e. "MyName" is treated the same as "myname" and "mYnAMe". The only exception is the "command" trigger, but you do not need to worry about this for now.\par
\par
Some terminology\par
----------------\par
When we say "group", we mean any block of lines of text beginning with something that looks like [groupname], and ending before the next group. For example, the group "Blah" consists of the first three lines in the following:\par
\par
\pard\nowidctlpar\li360 [Blah]\par
line1\par
line2\par
[Group 2]\par
more lines\par
\pard\nowidctlpar\par
Within a group, the parameters can appear in any order. So,\par
\par
\pard\nowidctlpar\li360 [SomeGroup]\par
value1 = 1234\par
value2 = "A string"\par
\pard\nowidctlpar\par
is equivalent to:\par
\par
\pard\nowidctlpar\li360 [SomeGroup]\par
value2 = "A string"\par
value1 = 1234\par
\pard\nowidctlpar\par
\par
\par
====================================================================\par
II. Player Variables\par
====================================================================\par
\par
No full documentation yet. See chars/kfm/kfm.cns for comments on each variable.\par
\par
Some importants one to note:\par
- In [Size], you can use "xscale" and "yscale" to change the width and height of your character. This saves the trouble of scaling every single one of the sprites. \par
- Set up the speeds of the player in [Velocity]\par
- Set the player's downward acceleration -- "yaccel" in [Movement]\par
\par
\par
\par
====================================================================\par
III. States\par
====================================================================\par
\par
a. Overview of Finite State Machines in MUGEN\par
b. Introduction to States\par
c. Basic Parts of a State\par
d. Details on StateDef\par
e. Details on State Controllers\par
f. Common states (common1.cns)\par
\par
\par
-------------------------------------------------\par
III.a. Overview of Finite State Machines in MUGEN\par
-------------------------------------------------\par
\cf0\par
This section presents a working (heuristic) characterization of finite state machines, as found in MUGEN. It is not especially technical, but it is aimed at the analytically minded reader. Feel free to skip over this section if you are already familiar with finite state machines, or if you are not interested in the details.\par
\par
A finite state machine (henceforth abbreviated FSM) is an automaton with a finite set of subroutines, each of which performs some function and then employs some criterion to choose the next subroutine to jump to. Each subroutine is called a "state", and the FSM is said to be in a given state when it is currently processing the directives in that state. A FSM can only be in one state at any given time.\par
\par
The following is a trivial example of a FSM, given in pseudocode.\par
\par
State 0:\par
1. Read in a number.\par
2. If the number is 0, go to state 0. Else, go to state 1.\par
\par
State 1:\par
1. Print "Woohoo!"\par
2. Go to state 3.\par
\par
State 2:\par
1. Go to state 0.\par
\par
State 3:\par
1. Quit\par
\par
Suppose this FSM starts in state 0 and reads in the value 0. Then it will return to the beginning of state 0, and read another number. This will continue until the FSM reads a nonzero number, at which point it will switch to state 1. In state 1, the FSM prints "Woohoo!" and then switches to state 3. State 3 causes the FSM to quit. State 2 is never reached in this example.\par
\par
Here's a state out of an FSM which might be used for a fighting game character.\par
\par
State 555:\par
1. Try to punch the other guy.\par
2. If successful, and the user is holding punch, go to state 555 (chain  \par
   move).\par
3. If successful and the user is not holding punch, play recovery \par
   animation.\par
4. If not successful, play miss animation.\par
5. When the recovery or miss animation ends, go to state 0 (idle).\par
\par
Characters in MUGEN are finite state machines. The character's CNS file defines a number of states, each of which contains one or more state controllers. State controllers are what actually give the character its functionality, similarly to the instructions for our character's FSM given above. For instance, the controller HitDef allows the character to hit his opponent, the ChangeState controller allows the character to make a state transition, and the ChangeAnim controller allows  the character to play a specified animation. Each state controller is specified along with one or more test conditions, called "triggers" or "condition-type triggers," which must be satisfied in order for that controller to be executed.\par
\par
Each MUGEN character has three special states, numbered -1, -2, and -3. These are the only allowable states with negative numbers. State -1 generally contains state controllers that determine state transition rules based on user input (commands). State -2 contains other state controllers that need to be checked every tick. State -3 contains state controllers which are checked every tick unless the player is temporarily using another player's state data (for instance, when the player is being thrown).\par
\par
For each tick of game-time, MUGEN makes a single pass through each of the special states, from top to bottom, in order of increasing state number (-3, -2, then -1). For each state controller encountered, its condition-type triggers are evaluated and, if they are satisfied, the controller is executed. Then processing proceeds to the next state controller in the state. A state transition (ChangeState) in any of the special states will update the player's current state number, but will not abort processing of the special states. After all the state controllers in the special states have been checked, the player's current state is processed, again from top to bottom. If a state transition is made out of the current state, the rest of the state controllers (if any) in the current state are skipped, and processing continues from the beginning of the new state. When the end of the current state is reached and no state transition is made, processing halts for this tick.\par
\par
There is one exception to the above scenario. If the character is a "helper" character, i.e., spawned by the Helper state controller, that character will not have the special states -3 and -2. The helper character will not have the special state -1 either, unless it has keyboard input enabled. (This is controlled by the Helper state controller when the character is created.)\par
\par
Note for the technically minded: A character's state machine might be considered an "impure" FSM, since there are a number of implicit state transition rules which are not user-specified. For instance, hitting the character causes a state transition which is not explicitly coded into the character's CNS. Furthermore, a single CNS state is usually much more complex than a state in a typical FSM as considered in mathematics or computer science. In any case, you will not find the rigorous definition of an FSM especially applicable to working with MUGEN.\par
\cf1\par
\par
-----------------------------\par
III.b. Introduction to States\par
-----------------------------\par
\par
Programming states is the hardest part of creating a character. It entails a lot of work, testing, and sometimes trial-and-error. In this section, we'll often refer the player being programmed, and to his opponent as well. Let us call the player whose states we are editing P1, and his opponent P2.\par
\par
Do not be discouraged if you do not understand a lot of this document on your first reading. The best way to learn about states is to first play around with values in the CNS of a completed character, and see what effects they have on him or her. There's nothing to fear from "tweaking" the CNS; M.U.G.E.N is designed to detect syntax errors and report them.\par
\par
Included with the M.U.G.E.N distribution package is a character named Kung Fu Man (KFM for short.) You can find him in the directory chars/kfm.\par
\par
The CMD file contains declarations of command names and the definition of State -1, a special state which is used to control how the character responds to user input. See the CMD document for more information.\par
\par
Here are some concepts that will be useful for you to know:\par
1. Life and power\par
2. Control\par
3. Game-time and state-time\par
4. Position, velocity and acceleration\par
5. Juggling\par
\par
1. Life and power\par
\pard\nowidctlpar\li360 A player's life bar is the yellow bar at the top of the screen on his side of the screen. When the life bar reaches zero, the player is knocked out. His power bar is the blue bar, and that increases with each attack he gives or takes. When the power bar reaches certain values, he can do super moves.\par
\pard\nowidctlpar\par
2. Control\par
\pard\nowidctlpar\li360 When we say a player "has control", we mean that he is ready to walk or jump or attack. A player who does not have control will not respond to your input (from keyboard or joystick). For example, when P1 is in his stand state, he has control, and will walk forward if you press the forward button. A player will typically not have control when he is in an attack state, otherwise you could just walk away halfway through a punch.\par
\par
There is an exception to the rule, however. Sometims you can let the player respond to certain moves even if he has no control. That is called a "move interrupt", or a "move cancel". See the CMD documentation for details.\par
\par
We will frequently refer to a player's "control flag". A "flag" is a value that is either true, or false. If we say the player's control flag is true, then it means he has control.\par
\pard\nowidctlpar\par
3. Game-time and state-time\par
\pard\nowidctlpar\li360 M.U.G.E.N keeps track of the time that has passed in the game. Every time the game is updated (this includes updating the players, checking collisions, and drawing to the screen), we say game-time has increased by one.\par
The time a player has spent in a state is known as the "state-time". The state-time starts at 0 at the beginning of a state, and increases by one tick for every tick of game-time.\par
\pard\nowidctlpar\par
4. Position, velocity and acceleration\par
\pard\nowidctlpar\li360 Those of you with basic knowledge of math should understand these concepts. M.U.G.E.N uses the following coordinate system.\par
The greater the X-position, the farther right the player is. The less the X-position, the closer he is to the left.\par
A Y-position of zero is at ground level. As the player's Y-position gets larger he moves downwards. For example, a negative Y-position means he is in the air.\par
Similarly, when we say a player has positive X-velocity, it means he is moving forward, and if he as negative X-velocity, he is moving backwards. A player with positive Y-velocity is moving downward, and a negative Y-velocity means he is moving up.\par
A positive X-acceleration means the player's X-velocity is increasing, a negative X-acceleration means his X-velocity is decreasing. Likewise for Y-acceleration.\par
\pard\nowidctlpar\par
5. Juggling\par
\pard\nowidctlpar\li360 M.U.G.E.N allows for certain moves to "juggle", that is, to hit opponents who have been knocked into the air, or are lying down on the ground. The juggling system works this way: each person starts with a set number of juggle "points" on the first hit that makes them fall, typically 15.\par
Some quick terminology: when we say a player is "falling", then we mean he does not recover control in the air, and will fall onto the ground.\par
If a player is hit while he is in the falling in the air or lying down on the ground, then his juggle points will decrease by an amount depending on the attack. When an attack requires more juggle points than the opponent has left, then the attack will miss. Any move that causes the opponent to fall immediately subtracts its juggle points on the first hit.\par
For example, an attack that requires 7 juggle points could theoretically be used to juggle the opponent twice (assuming you started with 15 points), leaving the opponent with 1 point left. Subsequent such attacks will miss.\par
The reason for this juggle system is to prevent infinite combos in the air.\par
\pard\nowidctlpar\par
\par
-----------------------------\par
III.c. Basic Parts of a State\par
-----------------------------\par
\par
Note: This section assumes you have at least browsed the documentation of AIR files, and understand the concepts of animation, as know the meaning of key words and phrases such as action and element of an action.\par
\par
Here is a short example state for P1:\par
\par
\pard\nowidctlpar\li360 [Statedef 200]\par
type = S\par
physics = S\par
movetype = I\par
ctrl = 0\par
anim = 200\par
velset = 0\par
\par
[State 200, 1]\par
type = ChangeState\par
trigger1 = AnimTime = 0\par
value = 0\par
ctrl = 1\par
\pard\nowidctlpar\par
This state plays back the Action 200 of P1's animation, and returns P1 to his standing state after the animation has ended. In this case, assume Action 200 has a finite looptime. That is, Action 200 does not have any elements with time equal to -1.\par
\par
At this point, you do not need to worry about the details. Let us begin by knowing what a state consists of.\par
\par
All states must have a single Statedef section and one or more State sections. \par
\par
Statedef contains the starting information of a state, such as what kind of state it is (standing, crouching, in the air) and what kind of move he is doing (attacking, idling.) \par
\par
Each State section is referred to as a state controller, or a controller for short. Controllers tell the program what to do to P1, and when to do it. There are many kinds of controllers, each with its own function. For example, there are controllers to change the players position or velocity, define the effects of attacks, create projectiles, switch between animation Actions, change states, and so on. Each controller must have at least one trigger. A trigger is an event that causes the controller to be activated. Examples are: trigger at the start of the state, trigger at the end of the animation (as seen in the example State above), trigger on an element of an animation Action, trigger when P2 is within a certain range of P1, and so on.\par
\par
\par
--------------------------\par
III.d. Details on StateDef\par
--------------------------\par
\par
Every state must begin with exactly one StateDef group, also known as a Statedef section. A StateDef group must look like this (put in one or more parameters where the dots are):\par
\pard\nowidctlpar\li360 [Statedef \i state_number\i0 ]\par
. \i state_parameters\i0\par
.\par
.\par
\pard\nowidctlpar Replace \i state_number\i0  with the number of the state you are programming. With the exception of the special group numbers (see Appendix A) you are allowed to use any state number you choose. To avoid choosing a special group number, do not choose numbers from 0-199, and from 5000-5999.\par
\par
The lines that follow should include the following parameters:\par
1. type\par
2. movetype\par
3. physics\par
4. anim\par
\par
1. type\par
\pard\nowidctlpar\li360 This is the state type of P1 in that state. It defines if he is standing, crouching, in the air, or lying down. The corresponding values are "S", "C" , "A" and "L" respectively (without the quotation marks). To leave the type unchanged from the previous state, use a value of "U". If this line is omitted, it assumes the type is "S". You will most commonly use "S", "C" and "A". For example, a crouching state type would require the line:\par
\par
type = C\par
\par
The type is used to determine several factors, most importantly, how P1 will react to being hit. For example, being in a "stand"-type state, P1 will react as if he is standing on the ground. If the type was "air", then P1 would react to the hit accordingly.\par
\pard\nowidctlpar\par
2. movetype\par
\pard\nowidctlpar\li360 This is the type of move P1 is doing: "A" for attack, "I" for idle and "H" for being hit. To leave the movetype unchanged from the previous state, use a value of "U". The value is assumed to be "I" if this line is omitted. "A" and "H" should be self-explanatory. "I" is used for states where P1 is neither attacking, nor being hit. For example, an attack state should have the line:\par
\par
movetype = A\par
\par
You need to specify the movetype so the program will know how to process the state. Incorrectly specifying the movetype may cause P1 to act incorrectly.\par
\pard\nowidctlpar\par
3. physics\par
\pard\nowidctlpar\li360 You need to specify what physics to use in that state. Valid values are "S" for stand, "C" for crouch, "A" for air, and "N" for none. To leave the physics unchanged from the previous state, use a value of "U". If omitted, the value of "N" is assumed. The kind of physics is used to determine how P1 behaves.\par
\par
For "S" physics, P1 will experience friction with the ground. The value for the friction coefficient is set in the Player Variables (see section II).\par
For "C" physics, P1 will experience friction, just like in the "S" state.\par
For "A" physics, P1 will accelerate downwards, and if his Y-position is greater than 0 (ie. he touches the ground) he will immediately go into his landing state.\par
If you use "N" P1 will not use any of these pre-programmed physics.\par
\par
Do not confuse "physics" with the state "type". They are usually the same, but you are given the choice if you want more control. For instance, you may choose to use "N" (no physics), and specify your own acceleration and landing detection for an aerial state.\par
\pard\nowidctlpar\par
4. anim\par
\pard\nowidctlpar\li360 This parameter changes the Animation Action of P1. Specify the action number as the value. If you do not want P1 to change animation at the start of the state, omit this parameter.\par
\pard\nowidctlpar\par
So to have a state with number 400, where the player is doing a crouching attack with Action 400, the typical parameters would be:\par
\par
\pard\nowidctlpar\li360 [Statedef 400]\par
type = c\par
movetype = a\par
physics = c\par
anim = 400\par
\pard\nowidctlpar\par
\par
The other optional parameters that you can use are:\par
4. velset\par
5. ctrl\par
6. poweradd\par
7. juggle\par
8. facep2\par
9. hitdefpersist\par
10. movehitpersist\par
11. hitcountpersist\par
12. sprpriority\par
\par
4. velset\par
\pard\nowidctlpar\li360 You can use velset to set P1's velocity at the beginning of the state. The format is a number pair, representing the x velocity and the y velocity respectively. Omitting this line will leave P1's velocity unchanged. For example, \par
\pard\nowidctlpar\li720 velset = 4,-8\par
\pard\nowidctlpar\li360 makes P1 start moving diagonally up and forwards.\par
There is an exception to this. Even if you have velset = 0, attacking P2 in the corner will push P1 away.\par
\pard\nowidctlpar\par
5. ctrl\par
\pard\nowidctlpar\li360 This parameter will set P1's control. A value of "0" sets the flag to false, "1" sets it to true. If omitted, P1's control flag is left unchanged. For example, to give P1 control, use\par
\pard\nowidctlpar\li720 ctrl = 1\par
\pard\nowidctlpar\par
6. poweradd\par
\pard\nowidctlpar\li360 When included, the poweradd parameter adds to the player's power bar. The value is a number, and can be positive or negative. This parameter is typically used in attack moves, where you want the player to gain power just by performing the attack. For example, to add 40 power, type\par
\pard\nowidctlpar\li720 poweradd = 40\par
\pard\nowidctlpar\par
7. juggle\par
\pard\nowidctlpar\li360 The juggle parameter is useful only for attacks. It specifies how many points of juggling the move requires. If omitted for an attack, that attack will juggle if the previous attacking state successfully juggled. You should include the juggle parameter for all attacks. If an attack spans more than one state, include the juggle parameter only in the first state of that attack. Juggling was explained in detail in "Useful Concepts" in Section IIIa.\par
\pard\nowidctlpar\par
8. facep2\par
\pard\nowidctlpar\li360 When you include the line "facep2 = 1", the player will be turned, if necessary, to face the opponent at the beginning of the state. "facep2" has the default value of "0" if omitted.\par
\pard\nowidctlpar\par
9. hitdefpersist\par
   If set to 1, any HitDefs which are active at the time of a state \par
   transition to this state will remain active. If set to 0, the\par
   default, any such HitDefs will be disabled when the state \par
   transition is made.\par
\par
10. movehitpersist\par
\pard\nowidctlpar\li360 If set to 1, the move hit information from the previous state (whether the attack hit or missed, guarded, etc; see Move* triggers in trigger docs) will be carried over into this state. If set to 0 (the default), this information will be reset upon entry into this state. \par
\pard\nowidctlpar\par
11. hitcountpersist\par
   If set to 1, the hit counter (how many hits this attack has done) \par
   will be carried over from the previous state to this state. If set \par
   to 0 (the default), the hit counter will be reset upon state \par
   transition. This parameter does not affect the combo counter which \par
   is displayed on the screen. See the hitcount and uniqhitcount\par
   trigger documentation for how to check the hit counter.\par
\par
12. sprpriority\par
   If this parameter is present, the player's sprite layering\par
   priority will be set to the value specified. If omitted, the\par
   sprite priority will be left unchanged. common1.cns (the CNS file\par
   that is inherited by every player) defines the sprite priority of\par
   standing or crouching players to be 0, and jumping players to be 1.\par
   For most attack states, you will want to set sprpriority = 2, so\par
   that the attacker appears in front. \par
   See SprPriority in the sctrls documentation for how to change\par
   sprite priority using a controller.\par
\par
\par
-----------------------------------\par
III.e. Details on State Controllers\par
-----------------------------------\par
\par
d.1 Controller Format\par
d.2 Triggers\par
d.3 Commonly-used controllers\par
\par
\par
III.d.1 Controller Format\par
-------------------------\par
\par
All states must have at least one state controller, otherwise it will cause an error. State controller groups have the following format:\par
\pard\nowidctlpar\li360 [State \i state_number\i0 ,\i  some_number\i0 ]\par
type = \i controller_type\i0\par
trigger1 = \i condition_exp\par
\i0 .\i   universal optional parameters\i0\par
.  \i additional parameters depending on controller\i0\par
.\par
.\par
\pard\nowidctlpar\par
The \i state_number\i0  must be the same number of the state from the statedef. \i some_number\i0  can be any number you choose; it is the number that is reported when an error is found, so you know which controller needs to be fixed. \par
\par
The universal (applicable to all state controllers) optional parameters are the ignorehitpause and persistency parameters. If ignorehitpause is set to 1, MUGEN will check this state controller even if the character is paused by a hit. Otherwise, this state controller will not be checked during a hit pause. The default is 0, which is recommended for all but exceptional situations. For an explanation of the persistency parameter, see the section on trigger persistency.\par
\par
The \i controller_type\i0  is the name of the controller you are using. Each type of controller has a different effect, and requires different parameters. See sctrls.txt for a full list of state controllers.\par
\par
The order of the controllers is significant. Controllers listed first are the ones checked and, if necessary, activated first.\par
\par
Here is an example of a controller that gives P1 control at the start of the state (the same effect as putting "ctrl = 1" as a parameter in the StateDef):\par
\par
\pard\nowidctlpar\li360 [State 300, 1] ;State 300. 1 is just an arbitrary number.\par
type = CtrlSet ;Changes the control flag.\par
trigger1 = Time = 0\par
value = 1\par
\pard\nowidctlpar\par
In this example, the CtrlSet type lets you change the control flag of P1. The line that reads "trigger1 = Time = 0" means that this controller is activated when the state-time is 0, ie. at the start of that state. The line "value = 1" says that we want to set the value of the control flag to 1, which means true. If we want to make P1 start the state with no control, then we just need to change the last line to "value = 0".\par
\par
Let's look another example. This controller moves P1 forwards by 10 pixels twice: on the second and third element of his current Animation Action. Don't worry if you don't know what parameters go with which controller types. You can learn more about them from the state controller documentation (sctrls).\par
\par
\pard\nowidctlpar\li360 [State 300, 2]\par
type = PosAdd ;Adds to P1's position\par
trigger1 = AnimElem = 2 ;Trigger on 2nd element.\par
trigger2 = AnimElem = 3 ;Trigger on 3rd element.\par
x = 10\par
\par
\pard\nowidctlpar As you see above, each controller must have at least one trigger. A trigger is a condition that causes the controller to be activated. This example has two triggers, and the controller is activated when EITHER ONE is true.\par
\par
\par
III.d.2 Triggers\par
----------------\par
\par
\ul i. Trigger logic\par
\ulnone\par
The first trigger should always be "trigger1", and subsequent triggers should be "trigger2", then "trigger3" and so on. The logic for deciding if a controller should be activated is:\par
1. Are all conditions of "trigger1" true? If so, then yes, activate the controller.\par
2. Otherwise, repeat the test for "trigger2", and so on, until no more triggers are found.\par
This can be thought of as "OR" logic.\par
\par
Be careful; skipping numbers will cause some triggers to be ignored. For example, if you have triggers "trigger1", "trigger2" and "trigger4" without a "trigger3", then "trigger4" will be ignored.\par
\par
Now what if you want more than one condition to be met before the controller is activated? Here is an commonly-used example for testing if a player in the air has reached the ground. The triggers used are:\par
\pard\nowidctlpar\li360 trigger1 = Vel Y > 0 ; True if Y-velocity is > 0 (going down)\par
trigger1 = Pos Y > 0 ; True if Y-position is > 0 (below ground)\par
\pard\nowidctlpar At this point, you may be confused by the format of the trigger. Do not worry about it for now. We will get to it soon.\par
As you can see above, both the triggers have the same number. When several triggers have the same number, it implements the "AND" logic. That is, the controller is activated if every one of the triggers with the same number is true, but not if one or more of them is false.\par
\par
You can combine both ideas. For example:\par
\pard\nowidctlpar\li360 trigger1 = Vel Y > 0 ; True if Y-velocity is > 0 (going down)\par
trigger1 = Pos Y > 0 ; True if Y-position is > 0 (below ground)\par
trigger2 = Time = 5  ; True if state-time is 5\par
\pard\nowidctlpar The controller for this would be activated if the player landed on the ground (Y-velocity and Y-Position are both > 0), OR if his state time was 5.\par
\par
Here is a summary:\par
- Triggers with the same number activate the controller only if all of them are true.\par
- Triggers with different numbers activate the controller if any one or more of them are true.\par
\par
The format of a trigger is:\par
\pard\nowidctlpar\li360 trigger? = \i trigger_type\i0  \i trigger_test\i0\par
\pard\nowidctlpar\i trigger_type\i0  is the name of the trigger (see triggers.txt for the full list). \par
\par
\i condition_exp\i0  is an arithmetic expression to be checked for equality to 0. If \i condition_exp\i0  is 0, then the trigger is false. If \i condition_exp\i0  is nonzero, then the trigger is true. The \i condition_exp\i0  is usually a simple relational expression as in the examples above, but can be as simple or as complicated as required. \par
\par
It is possible to use logical operators between expressions. For instance, this is equivalent to the previous example above.\par
\pard\nowidctlpar\li360 trigger1 = ((Vel Y > 0) && (Pos Y > 0)) || Time = 5\par
\pard\nowidctlpar See exp.txt for a detailed explanation of arithmetic expressions.\par
\par
A useful shortcut you might use is "triggerall". It determines a condition that must be true for all triggers. For instance in:\par
\par
\pard\nowidctlpar\li360 triggerall = Vel X = 0\par
trigger1 = Pos Y > -2\par
trigger2 = AnimElem = 3\par
trigger3 = Time = [2,9]\par
\pard\nowidctlpar\par
For any of trigger1 to trigger3 to be checked, the triggerall condition must be true too. In this case, as long as the X-velocity is not 0, then the state controller will not be activated. You can have more than one triggerall condition if you need. Note that at least one trigger1 must be present, even if you specify triggeralls.\par
\par
\ul ii. Trigger persistency\par
\ulnone\par
In the case where you do not want the trigger to activate every single time the condition is true, you will need to add a "persistent" paramter. Let us begin with an example:\par
\par
\pard\nowidctlpar\li360 [State 310, 1]\par
type = PosAdd\par
trigger1 = Vel Y > 1\par
x = 10\par
\pard\nowidctlpar\par
This state controller moves P1 forwards by 10 pixels for every tick of game time where P1's Y-velocity is greater than 1. That is, the controller is being activated everytime the trigger condition is true. If we want the controller to be activated only once, we will need to add a line:\par
\par
\pard\nowidctlpar\li360 [State 310, 1]\par
type = PosAdd\par
trigger1 = Vel Y > 1\par
persistent = 0       ;<-- Added this line\par
x = 10\par
\pard\nowidctlpar\par
"Persistent" has a default value of 1, meaning that the controller is activated everytime the trigger is true.\par
Setting "persistent" to 0 allows the controller to be activated only once during that state. This holds true until P1 leaves that state. If P1 returns to that state later, the controller can be activated once again.\par
\par
The "persistent" parameter can also take values other than 0 and 1:\par
\par
\pard\nowidctlpar\li360 [State 310, 1]\par
type = PosAdd\par
trigger1 = Vel Y > 1\par
persistent = 2       ;<-- Modified this line\par
x = 10\par
\pard\nowidctlpar\par
In this case, setting "persistent" to 2 means the controller will be activated once of every two times the trigger is true. Setting "persistent" to 3 activates the controller every 3rd time, and so on.\par
\par
\ul iii. Trigger redirection\par
\ulnone\par
One might wish to check the statetime of the player's target, or the player's parent (if the player is a helper), etc.\par
\par
\par
III.d.3 Commonly-used controllers\par
---------------------------------\par
\par
The "Null" controller will be useful for debugging. A "null" controller basically does nothing. You can use it to temporarily turn off certain controllers, instead of commenting out the entire section. For example, you might want to disable this:\par
\par
\pard\nowidctlpar\li360 [State 300, 1] ;Controller that accelerates P1 forwards\par
type = VelAdd\par
trigger1 = Time >= 0\par
x = .8\par
\pard\nowidctlpar\par
Simply comment out the type and put in "null":\par
\par
\pard\nowidctlpar\li360 [State 300, 1] ;Controller that accelerates P1 forwards\par
type = null ;VelAdd\par
trigger1 = Time >= 0\par
x = .8\par
\pard\nowidctlpar\par
Later, when you want to reenable the controller, just change the type back to what it used to be.\par
\par
Now let us look back at the example:\par
\par
\pard\nowidctlpar\li360 [Statedef 200]\par
type = S\par
physics = S\par
movetype = I\par
ctrl = 0\par
anim = 200\par
velset = 0\par
\par
[State 200, 1]\par
type = ChangeState\par
trigger1 = AnimTime = 0\par
value = 0\par
ctrl = 1\par
\pard\nowidctlpar\par
[State 200, 1] is a "ChangeState" controller. As the name implies, it changes P1's state number. The "value" parameter should have the number of the state to change to. The optional "ctrl" parameter can be set P1's control flag as he changes states.\par
\par
Now let's make this an attack state. First of all, the animation action needs attack collision boxes. A quick review from the air documentation: Clsn1 is for attack and Clsn2 is where the player can be hit. So P1 will hit P2 if any one of P1's Clsn1 boxes intersects with any of P2's Clsn2 boxes.\par
\par
As an example, let's assume the animation action in P1's AIR file looks like this:\par
\par
\pard\nowidctlpar\li360 [Begin Action 200]\par
200,0, 0,0, 3\par
200,1, 0,0, 4\par
200,2, 0,0, 4\par
200,3, 0,0, 3\par
\pard\nowidctlpar\par
After defining the bounding boxes, it looks like:\par
\par
\pard\nowidctlpar\li360 [Begin Action 200]\par
Clsn2: 1\par
  Clsn2[0] = -10,0, 10,-80\par
200,0, 0,0, 3\par
Clsn1: 1\par
  Clsn1[0] =  10,-70, 40,-60\par
Clsn2: 2\par
  Clsn2[0] = -10,  0, 10,-80\par
  Clsn2[1] =  10,-70, 40,-60\par
200,1, 0,0, 4\par
Clsn2Default: 1 ;Use this box for the last two frames\par
  Clsn2[0] = -10,0, 10,-80\par
200,2, 0,0, 4\par
200,3, 0,0, 3\par
\pard\nowidctlpar\par
As you can see, each element has a Clsn2 box defined for it (the last two elements are using the same boxes). The second element is the only one with a Clsn1 box.\par
\par
Note: It is all right to define Clsn1 boxes for any elements in an Animation Action, but if you put a Clsn1 box in the very first element, the attack will be instantaneous, and become unblockable. Therefore, it is recommended that you define Clsn1 boxes only for elements after the first one.\par
\par
Now we are ready to set up the state in the CNS. We will explain the changes below.\par
\par
\pard\nowidctlpar\li360 [Statedef 200]\par
type = S\par
physics = S\par
movetype = A  ;<-- changed from "I" to "A"\par
ctrl = 0\par
anim = 200\par
velset = 0\par
\par
[State 200, 1] ;<-- Added this state controller\par
type = HitDef\par
trigger1 = AnimElem = 2\par
attr = S, NA\par
animtype  = Light\par
damage    = 10\par
guardflag = MA\par
pausetime = 12,12\par
sparkxy = 0,-55\par
hitsound   = 5,0\par
guardsound = 6,0\par
ground.type = High\par
ground.slidetime = 12\par
ground.hittime  = 15\par
ground.velocity = -5\par
air.velocity = -2.5,-3.5\par
\par
[State 200, 2]\par
type = ChangeState\par
trigger1 = AnimTime = 0\par
value = 0\par
ctrl = 1\par
\pard\nowidctlpar\par
The "movetype" parameter in the StateDef is set to "A" for "attack". Remember to do this for all attack states. As before, P1 changes back to his standing state after his animation is over.\par
\par
That HitDef controller looks like a monster! Do not worry, we will go through it slowly.\par
\par
L1: type = HitDef\par
L2: trigger1 = AnimElem = 2\par
This specifies the controller type as "HitDef", which stands for "Hit Definition". It is triggered on the second element of animation. Any Clsn2 box from the time the trigger was activated will take on this hit definition.\par
If, for example, you had a Clsn1 in both the second and third element of animation, triggering a single HitDef at the second element makes it apply to both elements of animation. So P1 will hit at most once: if the second element hits, the third will miss. If the second element misses, the third can still hit. To make the attack hit twice, you must trigger a HitDef for each of the two elements.\par
\par
L3: attr = S, NA\par
This is the attribute of the attack. It is used to determine if the attack can hit P2. In this case, it is a Standing Normal Attack.\par
"attr" has the format:\par
\pard\nowidctlpar\li360 attr = \i arg1\i0 , \i arg2\i0\par
\pard\nowidctlpar Where:\par
- arg1 is either "S", "C" or "A". Similar to "statetype" for the StateDef, this says whether the attack is a standing, crouching, or aerial attack.\par
- arg2 is a 2-character string. The first character is either "N" for "normal", "S" for "special", or "H" for "hyper" (or "super", as it is commonly known). The second character must be either "A" for "attack" (a normal hit attack), "T" for "throw", or "P" for projectile.\par
\par
L4: animtype = Light\par
This refers to the type of animation that P2 will go into when hit by the attack. Choose from "light", "medium", "hard" or "back". The first three should be self-explanatory. "Back" is the animation where P2 is knocked off her feet.\par
\par
L5: damage = 10\par
This is the damage that P2 takes when hit, and it does no damage if guarded. If we changed that line to "damage = 10, 1", then it will do 1 point of damage if guarded.\par
\par
L6: guardflag = MA\par
"Guardflag" determines how P2 may guard the attack. Here, it may be guarded high(standing), low (crouching) and in the air. The argument must be a string of characters that includes any of the following: "H" for "high", "L" for "low" or "A" for air. "M" (mid) is equivalent to saying "HL".\par
\par
L7: pausetime = 12,12\par
This is the time that each player will pause on the hit. The first argument is the time to freeze P1, measured in game-ticks. The second is the time to make P2 shake before recoiling from the hit.\par
\par
L8: sparkxy = 0,-55\par
This is where to make the hit/guard spark. The arguments must be in the form "x, y". x is relative to the front of P2. A negative x makes a spark deeper inside P2. y is relative to P1. A negative y makes a spark higher up.\par
\par
L9: hitsound = 5,0\par
This is the sound to play on hit (from fight.snd). The included fight.snd lets you choose from 5,0 (light hit sound) through to 5,4 (painful whack). To play a sound from the player's own SND file, precede the first number with an "S". For example, "hitsound = S1,0".\par
\par
L10: guardsound = 6,0\par
This is the sound to play on guard (from fight.snd). Right now all we have is 6,0. To play a sound from the player's own SND file, precede the first number with an "S".\par
\par
L11: ground.type = High\par
This is the kind of attack for ground attacks (it also defaults to air attacks if you do not have "air.type = ?"). In this case, it is a high attack. Choose from "High" for attacks that make P2's head snap backwards, "Low" for attacks that look like that hit in the stomach, "Trip" for low sweep attacks, or "None" to not do anything to P2. "High" and "Low" attacks are the same on P2 if the AnimType is "Back".\par
\par
L12: ground.slidetime = 12\par
This is the time in game-ticks that P2 will slide back for after being hit (this time does not include the pausetime for P2). Applicable only to hits that keep P2 on the ground.\par
\par
L13: ground.hittime = 15\par
Time that P2 stays in the hit state after being hit. Applicable only to hits that keep P2 on the ground.\par
\par
L14: ground.velocity = -5\par
Initial X-velocity to give P2 after being hit, if P2 is in a standing or crouching state on the ground. You can specify a Y-velocity as the second argument if you want P2 to be knocked into the air, eg. "ground.velocity = -3, -2".\par
\par
L15: air.velocity = -2.5,-3.5\par
Initial velocity to give P2 if P2 is hit in the air\par
\par
There are more things that you can control in a HitDef. See sctrls.txt for details.\par
\par
\par
----------------------------------\par
III.f. Common states (common1.cns)\par
----------------------------------\par
\par
If you look at a player's DEF file, you will see the line:\par
stcommon = common1.cns  ;Common states\par
Every player shares some common states, which are the basic parts of the game engine. These common states are found in data/common1.cns. Some examples are states for running and getting hit. A full list is available in Appendix A, Special State Controller Numbers.\par
\par
If there is a common state that you would like to override for a certain player, all you need to do is make a state in that player's CNS with the same number as the one you would like to override. Then, when the player changes to that certain state number, he will enter that new state, instead of the one in common1.cns.\par
\par
You should remember that when overriding certain states that have special properties coded inside M.U.G.E.N, the new states you make will still have the same special properties as the ones you overrode. For example, the run state (state 100) sets the player's velocity to whatever values you specified in his player variables. If you override state 100, the new state will still have the property of setting that player's velocity.\par
\par
A common example is overriding the running state. M.U.G.E.N's default behaviour for the running state is to have the player continue moving forward at a constant speed, until you let go of the forward key. At that point he returns to the stand state.\par
\par
Now, let's say we want that player (let us call him P1) to instead hop forward, just like the default double-tap back hop. You can make a state in P1's CNS:\par
\pard\nowidctlpar\li360\par
\cf0 ; RUN_FWD (overridden to dash-type)\par
[Statedef 100]\par
type    = S   ;Running is on the ground\par
physics = N   ;We'll define our own physics\par
anim = 100    ;Anim action 100\par
ctrl = 0      ;No control for duration of dash\par
\par
[State 100, 1] ;To start dashing forwards\par
type = VelSet\par
trigger1 = Time = [0,5]\par
x = 6\par
\par
[State 100, 2] ;Friction after initial dash\par
type = VelMul\par
trigger1 = Time > 5\par
x = .85\par
\par
[State 100, 3] ;\par
type = ChangeState\par
trigger1 = AnimTime = 0\par
value = 0\par
ctrl = 1\par
\pard\nowidctlpar\cf1\par
Here, we assume that Action 100 has a finite looptime. The velocity in "\cf0 run.fwd" under [Velocity] of the player variables is not really ignored, but [State 100,1] overrides that detail by setting the X-velocity to 6.\cf1\par
\par
\par
\par
====================================================================\par
IV. Expressions\par
====================================================================\par
\par
MUGEN has support for expressions in both the CNS and the CMD files. This section will briefly cover some examples of expressions. Don't take this for a thorough reference; it is only a quick guide to get you started. For a complete explanation of expressions, please refer to the expressions documentation (exp).\par
\par
Expressions allow you to use a trigger as the value of a parameter. The following example increases the x-position of the player by a value that is equal to his state time.\par
\pard\nowidctlpar\li360\cf0\par
\cf1 [State 200, 1]\par
type = PosAdd\par
trigger1 = Time = 0\par
x = Time\par
\pard\nowidctlpar\par
Simple arithmetic is also possible using expressions. Some basic arithmetic operators are:\par
+ addition\par
- subtraction\par
* multiplication\par
/ division\par
\pard\nowidctlpar\li360\cf0\par
\cf1 [State 200, 1]\par
type = VelSet\par
\pard\nowidctlpar    trigger1 = 1   ;Note: this is logically equivalent to \par
   x = Time + 4   ;"trigger1 = Time >= 0"\par
\par
Expressions in state controller parameters are evaluated at runtime, meaning that every time a state controller with a parameter containing an expression is executed, the parameter's value is recalculated during that instant. In the example above, the player's x-velocity is recomputed for every frame that he stays in state 200.\par
\par
The order of evaluation generally left-to-right, but with multiplication and division taking precedence over addition and subtraction. For example, in an expression 5 + 6 / 2, the result is 8. To force the addition to take place before the division, you can add in parentheses, ie. (5 + 6) / 2, which gives a result of 5.5.\par
\par
Expressions may also be used in the trigger line. These expressions are evaluated every time the trigger is checked. This next example changes the player's state when his state time is greater than the value stored in the variable var(1).\par
\par
\pard\nowidctlpar\li360 [State 200, 1]\par
type = ChangeState\par
trigger1 = Time > var(1)\par
value = 201\par
\pard\nowidctlpar\par
Variables may also take expressions, as seen below.\par
\pard\nowidctlpar\li360\par
[State 200, 1]\par
type = VarSet\par
trigger1 = Time = [1,5]\par
var(Time) = Time * 2\par
\pard\nowidctlpar\par
Logical operators may also be used. || is used for "or", and && for "and". For example, this changes the player's state when his state time is greater than 90, and his animation has ended.\par
\par
\pard\nowidctlpar\li360 [State 200, 1]\par
type = ChangeState\par
trigger1 = Time > 90 && AnimTime = 0\par
value = 0\par
\pard\nowidctlpar\par
The trigger line above is logically equivalent to these two lines:\par
\par
\pard\nowidctlpar\li360 trigger1 = Time > 90\par
trigger1 = AnimTime = 0\par
\pard\nowidctlpar\par
&& takes precedence over ||. Whenever you use more than one logical operator in an expression, try to use brackets for clarity. It's not required, but it makes it easier to understand. For instance:\par
\par
\pard\nowidctlpar\li360 trigger1 = ((Time > 90) && (AnimTime = 0) || (var(2) = [5,9]))\par
\pard\nowidctlpar\par
Not all parameters support expressions. Typically, those that are of a non-numeric type do not support expressions. For example, this is an illegal construct:\par
\par
[State 300, 5]\par
type = HitDef\par
trigger1 = Time = 0\par
ground.type = High && Low    ; <-- illegal -- non-numeric types!\par
\par
\par
\par
====================================================================\par
Appendix A.  Special State Numbers\par
====================================================================\par
\par
Unless you plan to override a common state, avoid choosing state numbers in the range 0-199 and 5000-5999. Here is a list of states in common1.cns. State numbers labeled "reserved" should not be used, as they may be assigned special functionality in a later version of MUGEN.\par
\par
\par
Number      Description\par
------      -----------\par
0           Stand\par
10          Stand-to-crouch\par
11          Crouching\par
12          Crouch-to-stand\par
20          Walk\par
\par
This list is not yet complete. Please be patient.\par
\pard\cf0\par
}
 